<template>
  <div class="sight-management">
    <div class="page-header">
      <h2>景点管理</h2>
      <el-button type="primary" @click="handleAdd">新增景点</el-button>
    </div>

    <el-card class="filter-card">
      <el-form :inline="true" :model="filterForm" class="filter-form">
        <el-form-item label="景点名称">
          <el-input v-model="filterForm.name" placeholder="请输入景点名称" clearable style="width: 200px;" />
        </el-form-item>
        
        <el-form-item label="状态">
          <el-select v-model="filterForm.status" placeholder="全部状态" clearable @change="handleFilter" style="width: 100px;">
            <el-option label="开放" value="open" />
            <el-option label="关闭" value="closed" />
            <el-option label="维护中" value="maintenance" />
          </el-select>
        </el-form-item>
        
        <el-form-item label="最低评分">
          <el-rate
            v-model="filterForm.minRating"
            :max="5"
            :allow-half="true"
            @change="handleFilter"
          />
        </el-form-item>
        
        <el-form-item>
          <el-button type="primary" @click="handleFilter">查询</el-button>
          <el-button @click="resetFilter">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="table-card">
      <el-table
        v-loading="loading"
        :data="sightList"
        style="width: 100%"
        border
      >
        <el-table-column type="expand">
          <template #default="props">
            <div class="sight-detail">
              <div class="description">
                <strong>景点描述：</strong>
                <p>{{ props.row.description }}</p>
              </div>
              
              <!-- 设施服务 -->
              <div class="facilities-section" v-if="props.row.facilities && props.row.facilities.length">
                <strong>设施服务：</strong>
                <div class="facilities-tags">
                  <el-tag 
                    v-for="(facility, index) in props.row.facilities" 
                    :key="index" 
                    size="small" 
                    type="info"
                    class="facility-tag"
                  >
                    {{ facility }}
                  </el-tag>
                </div>
              </div>
              
              <!-- 参观须知 -->
              <div class="notice-section" v-if="props.row.notice">
                <strong>参观须知：</strong>
                <p class="notice-content">{{ props.row.notice }}</p>
              </div>
              
              <div class="images-section" v-if="props.row.images && props.row.images.length">
                <div class="images-header">
                  <strong>景点图片：</strong>
                  <span class="image-count">共 {{ props.row.images.length }} 张</span>
                </div>
                <div class="images-grid">
                  <el-image
                    v-for="(image, index) in props.row.images"
                    :key="index"
                    :src="image"
                    :preview-src-list="props.row.images"
                    :initial-index="index"
                    fit="cover"
                    :lazy="true"
                    class="sight-image"
                  >
                    <template #placeholder>
                      <div class="image-placeholder">
                        <el-icon><Picture /></el-icon>
                        <span>加载中...</span>
                      </div>
                    </template>
                    <template #error>
                      <div class="image-error">
                        <el-icon><PictureFilled /></el-icon>
                        <span>加载失败</span>
                      </div>
                    </template>
                  </el-image>
                </div>
              </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="name" label="景点名称" min-width="180">
          <template #default="scope">
            <div class="sight-name-cell">
              <span>{{ scope.row.name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="评分" width="150">
          <template #default="scope">
            <div class="rating-cell">
              <el-rate
                v-model="scope.row.rating"
                disabled
                :allow-half="true"
                :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
              />
              <span class="rating-count" v-if="scope.row.ratingCount">
                ({{ scope.row.ratingCount }})
              </span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="开放时间" width="200">
          <template #default="scope">
            <div class="time-cell">
              <el-icon><Clock /></el-icon>
              <span v-if="Array.isArray(scope.row.openTime)">{{ scope.row.openTime[0] }}至{{ scope.row.openTime[1] }}</span>
              <span v-else>{{ scope.row.openTime }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="address" label="地址" min-width="220">
          <template #default="scope">
            <div class="address-cell">
              <el-icon><Location /></el-icon>
              <el-tooltip 
                :content="scope.row.address" 
                placement="top" 
                :show-after="1000"
              >
                <span>{{ scope.row.address }}</span>
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="120">
          <template #default="scope">
            <div class="status-cell">
              <el-tag :type="getSightStatusType(scope.row.status)">
                {{ getSightStatusText(scope.row.status) }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="scope">
            <el-button
              type="primary"
              link
              size="small"
              @click="handleEdit(scope.row)"
            >
              编辑
            </el-button>
            <el-button
              type="danger"
              link
              size="small"
              @click="handleDelete(scope.row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'add' ? '新增景点' : '编辑景点'"
      width="650px"
    >
      <el-form
        ref="sightFormRef"
        :model="sightForm"
        :rules="sightRules"
        label-width="100px"
      >
        <el-form-item label="景点名称" prop="name">
          <el-input v-model="sightForm.name" />
        </el-form-item>

        <el-form-item label="景点描述" prop="description">
          <el-input
            v-model="sightForm.description"
            type="textarea"
            :rows="4"
          />
        </el-form-item>

        <el-form-item label="地址" prop="address">
          <el-input v-model="sightForm.address" />
        </el-form-item>

        <el-form-item label="开放时间" prop="openTime">
          <el-time-picker
            v-model="sightForm.openTime[0]"
            placeholder="开始时间"
            format="HH:mm"
            value-format="HH:mm"
            style="width: 120px; margin-right: 10px;"
          />
          <span style="margin: 0 10px;">-</span>
          <el-time-picker
            v-model="sightForm.openTime[1]"
            placeholder="结束时间"
            format="HH:mm"
            value-format="HH:mm"
            style="width: 120px;"
          />
        </el-form-item>

        <el-form-item label="评分" prop="rating">
          <el-rate
            v-model="sightForm.rating"
            :allow-half="true"
            :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
          />
        </el-form-item>

        

        <el-form-item label="设施服务">
          <el-checkbox-group v-model="sightForm.facilities">
            <el-checkbox label="停车场">停车场</el-checkbox>
            <el-checkbox label="餐厅">餐厅</el-checkbox>
            <el-checkbox label="卫生间">卫生间</el-checkbox>
            <el-checkbox label="商店">商店</el-checkbox>
            <el-checkbox label="导游服务">导游服务</el-checkbox>
            <el-checkbox label="无障碍设施">无障碍设施</el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <el-form-item label="参观须知" prop="notice">
          <el-input
            v-model="sightForm.notice"
            type="textarea"
            :rows="4"
            placeholder="请输入参观须知"
          />
        </el-form-item>

        <el-form-item label="状态" prop="status">
          <el-select v-model="sightForm.status">
            <el-option label="开放" value="open" />
            <el-option label="关闭" value="closed" />
            <el-option label="维护中" value="maintenance" />
          </el-select>
        </el-form-item>

        <el-form-item label="景点图片">
          <!-- 图片链接输入 -->
          <el-input
            v-model="imageLink"
            placeholder="请输入图片链接"
            class="image-link-input"
          >
            <template #append>
              <el-button @click="addImageFromLink">添加</el-button>
            </template>
          </el-input>
          
          <!-- 文件上传 -->
          <el-upload
            action="/upload"
            list-type="picture-card"
            :file-list="fileList"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemove"
            :before-upload="beforeUpload"
            :on-success="handleUploadSuccess"
            :multiple="true"
            :limit="8"
            class="image-uploader"
          >
            <template #default>
              <el-icon><Plus /></el-icon>
              <div class="upload-text">点击上传</div>
            </template>
            <template #tip>
              <div class="el-upload__tip">
                支持 jpg/png 格式图片，大小不超过 2MB，最多上传 8 张
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 图片预览 -->
    <el-dialog
      v-model="previewVisible"
      width="800px"
      class="preview-dialog"
      :append-to-body="true"
      :modal-class="'preview-modal'"
      :close-on-click-modal="true"
      destroy-on-close
    >
      <div class="preview-container">
        <div class="preview-image-wrapper">
          <img :src="previewImage" alt="Preview Image" class="preview-image" />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Clock, Location, Picture, PictureFilled } from '@element-plus/icons-vue'
import api from '@/services/api'

// 状态和数据
const loading = ref(false)
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const sightList = ref([])
const dialogVisible = ref(false)
const dialogType = ref('add')
const previewVisible = ref(false)
const previewImage = ref('')
const fileList = ref([])
const imageLink = ref('') // 图片链接输入

// 过滤表单
const filterForm = reactive({
  name: '',
  status: '',
  minRating: 0
})

// 查询模式：fuzzy(模糊) 或 exact(精确)
const searchMode = ref('fuzzy')

// 景点表单
const sightFormRef = ref(null)
const sightForm = reactive({
  name: '',
  description: '',
  address: '',
  openTime: ['', ''],
  rating: 5,
  status: 'open',
  images: [],
  facilities: [],
  notice: ''
})

// 表单验证规则
const sightRules = {
  name: [
    { required: true, message: '请输入景点名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  description: [
    { required: true, message: '请输入景点描述', trigger: 'blur' }
  ],
  address: [
    { required: true, message: '请输入景点地址', trigger: 'blur' }
  ],
  openTime: [
    { 
      validator: (rule, value, callback) => {
        if (!value || !Array.isArray(value) || value.length !== 2 || !value[0] || !value[1]) {
          callback(new Error('请选择完整的开放时间范围'))
        } else {
          // 验证时间格式是否正确 (HH:mm)
          const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/
          if (!timeRegex.test(value[0]) || !timeRegex.test(value[1])) {
            callback(new Error('时间格式不正确，请使用 HH:mm 格式'))
          } else {
            callback()
          }
        }
      },
      trigger: 'blur'
    }
  ],
  
  
}

// 获取景点列表
const getSights = async () => {
  loading.value = true
  try {
    // 构造查询参数
    const params = {
      page: currentPage.value,
      pageSize: pageSize.value,
      status: filterForm.status,
      minRating: filterForm.minRating
    };
    
    // 处理景点名称查询参数
    if (filterForm.name) {
      params.name = filterForm.name;
    }
    
    const response = await api.get('/sight', {
      params
    })
    sightList.value = response.data.data.items
    total.value = response.data.data.total
  } catch (error) {
    ElMessage.error('获取景点列表失败')
  } finally {
    loading.value = false
  }
}

// 状态映射
const getSightStatusText = (status) => {
  const statusMap = {
    open: '开放',
    closed: '关闭',
    maintenance: '维护中'
  }
  return statusMap[status] || status
}

const getSightStatusType = (status) => {
  const typeMap = {
    open: 'success',
    closed: 'danger',
    maintenance: 'warning'
  }
  return typeMap[status] || ''
}

// 新增景点
const handleAdd = () => {
  dialogType.value = 'add'
  Object.assign(sightForm, {
    name: '',
    description: '',
    address: '',
    openTime: ['', ''],
    rating: 5,
    status: 'open',
    images: [],
    facilities: [],
    notice: ''
  })
  fileList.value = []
  imageLink.value = '' // 清空图片链接输入框
  dialogVisible.value = true
}

// 编辑景点
const handleEdit = (row) => {
  dialogType.value = 'edit'
  Object.assign(sightForm, row)
  
  // 处理开放时间格式
  if (row.openTime && typeof row.openTime === 'string' && row.openTime.includes('-')) {
    const times = row.openTime.split('-')
    sightForm.openTime = [times[0], times[1]]
  } else {
    sightForm.openTime = ['', '']
  }
  
  fileList.value = (row.images || []).map((url, index) => ({
    name: `image-${index}`,
    url
  }))
  imageLink.value = '' // 清空图片链接输入框
  dialogVisible.value = true
}

// 删除景点
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确认删除该景点？此操作不可恢复', '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    await api.delete(`/sight/${row.sightId}`)
    ElMessage.success('删除成功')
    getSights()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

// 图片上传相关
const handlePictureCardPreview = (file) => {
  previewImage.value = file.url
  previewVisible.value = true
}

const handleRemove = (file) => {
  const index = sightForm.images.indexOf(file.url)
  if (index > -1) {
    sightForm.images.splice(index, 1)
  }
}

const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB!')
    return false
  }
  return true
}

const handleUploadSuccess = (response, file) => {
  sightForm.images.push(response.url)
}

// 通过链接添加图片
const addImageFromLink = async () => {
  if (!imageLink.value) {
    ElMessage.warning('请输入图片链接')
    return
  }
  
  // 验证URL格式
  try {
    new URL(imageLink.value)
  } catch (error) {
    ElMessage.error('请输入有效的图片链接')
    return
  }
  
  // 验证图片链接是否有效（可选）
  try {
    // 创建一个图片对象来验证链接是否指向有效的图片
    const img = new Image();
    img.onload = () => {
      // 图片加载成功，添加到图片列表
      sightForm.images.push(imageLink.value)
      imageLink.value = '' // 清空输入框
      ElMessage.success('图片链接添加成功')
    };
    img.onerror = () => {
      ElMessage.error('图片链接无效或无法访问')
    };
    img.src = imageLink.value;
  } catch (error) {
    ElMessage.error('图片链接验证失败')
  }
}

// 表单提交
const handleSubmit = async () => {
  if (!sightFormRef.value) return
  
  try {
    await sightFormRef.value.validate()
    
    // 处理开放时间格式
    const formData = { ...sightForm }
    if (Array.isArray(formData.openTime) && formData.openTime.length === 2) {
      formData.openTime = `${formData.openTime[0]}-${formData.openTime[1]}`
    } else if (Array.isArray(formData.openTime)) {
      formData.openTime = ''
    }
    
    if (dialogType.value === 'add') {
      await api.post('/sight', formData)
      ElMessage.success('添加成功')
    } else {
      await api.put(`/sight/${formData.sightId}`, formData)
      ElMessage.success('更新成功')
    }
    
    dialogVisible.value = false
    getSights()
  } catch (error) {
    ElMessage.error(dialogType.value === 'add' ? '添加失败' : '更新失败')
  }
}

// 过滤和分页
const handleFilter = () => {
  currentPage.value = 1
  getSights()
}

const resetFilter = () => {
  filterForm.name = ''
  filterForm.status = ''
  filterForm.minRating = 0
  handleFilter()
}

const handleSizeChange = (val) => {
  pageSize.value = val
  getSights()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  getSights()
}

// 初始加载
getSights()
</script>

<style scoped>
.sight-management {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0;
  font-weight: 600;
}

.filter-card {
  margin-bottom: 20px;
}

.filter-form {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.table-card {
  margin-bottom: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.sight-detail {
  padding: 20px;
  
  .description {
    margin-bottom: 20px;
    
    p {
      margin: 10px 0;
      white-space: pre-wrap;
      line-height: 1.6;
    }
  }
  
  .facilities-section {
    margin-bottom: 20px;
    
    .facilities-tags {
      margin-top: 10px;
      
      .facility-tag {
        margin-right: 10px;
        margin-bottom: 10px;
      }
    }
  }
  
  .notice-section {
    margin-bottom: 20px;
    
    .notice-content {
      margin: 10px 0;
      padding: 10px;
      background-color: #f5f7fa;
      border-radius: 4px;
      white-space: pre-wrap;
      line-height: 1.6;
    }
  }
  
  .images-section {
    margin-top: 20px;

    .images-header {
      display: flex;
      align-items: center;
      margin-bottom: 15px;

      .image-count {
        margin-left: 10px;
        color: #909399;
        font-size: 14px;
      }
    }
    
    .images-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
      gap: 15px;
      
      .sight-image {
        width: 100%;
        height: 180px;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        transition: all 0.3s ease;
        cursor: pointer;
        
        &:hover {
          transform: translateY(-5px);
          box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
        }

        :deep(.el-image__inner) {
          width: 100%;
          height: 100%;
          object-fit: cover;
          transition: transform 0.3s ease;
        }

        :deep(.el-image__placeholder),
        :deep(.el-image__error) {
          background-color: #f5f7fa;
          height: 100%;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          color: #909399;
          
          .el-icon {
            font-size: 32px;
            margin-bottom: 8px;
          }
          
          span {
            font-size: 14px;
          }
        }
      }
    }
  }
}

.preview-dialog {
  :deep(.el-dialog__header) {
    display: none;
  }

  :deep(.el-dialog__body) {
    padding: 0;
  }

  .preview-container {
    position: relative;
    width: 100%;
    background: transparent;

    .preview-image-wrapper {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 200px;
      max-height: 80vh;
      overflow: hidden;

      .preview-image {
        max-width: 100%;
        max-height: 80vh;
        object-fit: contain;
      }
    }
  }
}

.sight-name-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  
  .el-tag {
    font-weight: bold;
  }
}

.rating-cell {
  display: flex;
  align-items: center;
  gap: 4px;
  
  .rating-count {
    color: #909399;
    font-size: 12px;
  }
}

.time-cell, .address-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  
  .el-icon {
    color: #909399;
  }
  
  span {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

.status-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

:deep(.el-upload--picture-card) {
  --el-upload-picture-card-size: 120px;
  
  .upload-text {
    margin-top: 8px;
    font-size: 12px;
    color: #909399;
  }
}

:deep(.el-dialog__body) {
  padding-top: 20px;
}

:deep(.el-upload-list__item) {
  transition: transform 0.3s;
  
  &:hover {
    transform: scale(1.02);
  }
}

.image-link-input {
  margin-bottom: 15px;
}

.image-uploader {
  :deep(.el-upload--picture-card) {
    --el-upload-picture-card-size: 120px;
    
    .upload-text {
      margin-top: 8px;
      font-size: 12px;
      color: #909399;
    }
  }
}
</style>